import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:hive/hive.dart';
import 'package:info_manager/common/flatPanel.dart';
import 'package:info_manager/models/dsItem.dart';

import '../entry.dart';
import '../utils/screw.dart';

class DSEditorPage extends StatefulWidget {
  DSEditorPage({Key key, this.title = Entry.DSEditor}) : super(key: key);

  final String title;

  @override
  _DSEditorPageState createState() => _DSEditorPageState();
}

class _DSEditorPageState extends State<DSEditorPage> {
  var mViewState = ViewState.Initial;
  String mEntry;
  var mEntries = <String>[];
  DSItem mItem;
  Box<dynamic> mBox;

  final _entry = TextEditingController();
  final _host = TextEditingController();
  final _port = TextEditingController();
  final _user = TextEditingController();
  final _pwd = TextEditingController();
  final _db = TextEditingController();
  final GlobalKey _formKey = new GlobalKey<FormState>();

  @override
  void initState() {
    super.initState();
    if (!Hive.isAdapterRegistered(11)) Hive.registerAdapter(DSItemAdapter());
  }

  @override
  Future<void> dispose() async {
    super.dispose();
    if (mBox != null && mBox.isOpen) await mBox.close();
  }

  Future<void> openDb() async {
    var dirPath = await Screw.getUserFilePath('flutter');
    mBox = await Hive.openBox('dataSource', path: dirPath);
    if (!mBox.isOpen)
      Screw.showToast(context, '无法打开数据库!');
    else
      onUpdateEntries();
  }

  void _clean() {
    _entry.clear();
    _host.clear();
    _port.clear();
    _user.clear();
    _pwd.clear();
    _db.clear();
  }

  Future<void> onUpdateEntries() async {
    if (mBox.isOpen) {
      mEntries = mBox.get('entries', defaultValue: <String>[]);
    }
    if (mEntries.isEmpty) mEntries.add('Entry');
    setState(() {
      mEntry = mEntries.first;
      mViewState = ViewState.DetailView;
    });
  }

  Future<void> onUpdateView() async {
    if (mEntry.isEmpty) return;
    if (mBox.isOpen) {
      mItem = mBox.get(mEntry);
    }
    if (mItem != null)
      setState(() {
        _host.text = mItem.host;
        _port.text = mItem.port.toString();
        _user.text = mItem.user;
        _pwd.text = mItem.pwd;
        _db.text = mItem.db;
      });
  }

  void onAddItem() {
    _clean();
    setState(() {
      mViewState = ViewState.AddItemView;
    });
  }

  Widget _genHeaderWidget() {
    return DropdownButton<String>(
      isExpanded: true,
      hint: Text('Entry'),
      value: mEntry,
      items: mEntries
          .map((e) => DropdownMenuItem<String>(
                value: e,
                child: Text(e),
              ))
          .toList(),
      onChanged: (v) {
        mEntry = v;
        onUpdateView();
      },
    );
  }

  Future<void> _onSubmit() async {
    var item = DSItem(
      host: _host.text,
      port: int.tryParse(_port.text, radix: 10),
      user: _user.text,
      pwd: _pwd.text,
      db: _db.text,
    );
    if (mBox.isOpen) {
      if (mViewState == ViewState.AddItemView) {
        mEntry = _entry.text;
        await mBox.put(mEntry, item);
        List<String> items = mBox.get('entries', defaultValue: <String>[]);
        if (!items.contains(mEntry)) {
          items.add(mEntry);
          await mBox.put('entries', items);
        }
      } else {
        await mBox.put(mEntry, item);
      }

      _clean();
      onUpdateEntries();
    }
  }

  List<Widget> _genDetailWidgets() {
    var items = <Widget>[
      TextFormField(
        controller: _host,
        decoration: InputDecoration(
          hintText: 'Host',
          prefixIcon: Icon(Icons.title),
        ),
        validator: (v) => v.trim().length > 0 ? null : 'Host不能为空',
      ),
      TextFormField(
        controller: _port,
        keyboardType: TextInputType.number,
        decoration: InputDecoration(
          hintText: 'Port',
          prefixIcon: Icon(Icons.title),
        ),
        validator: (v) => v.trim().length > 0 ? null : 'Port不能为空',
      ),
      TextFormField(
        controller: _user,
        decoration: InputDecoration(
          hintText: 'UserName',
          prefixIcon: Icon(Icons.title),
        ),
        validator: (v) => v.trim().length > 0 ? null : 'UserName不能为空',
      ),
      TextFormField(
        controller: _pwd,
        decoration: InputDecoration(
          hintText: 'Password',
          prefixIcon: Icon(Icons.title),
        ),
        validator: (v) => v.trim().length > 0 ? null : 'Password不能为空',
      ),
      TextFormField(
        controller: _db,
        decoration: InputDecoration(
          hintText: 'Database',
          prefixIcon: Icon(Icons.title),
        ),
        validator: (v) => v.trim().length > 0 ? null : 'Database不能为空',
      ),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Expanded(
            flex: 1,
            child: FlatButton(
                child: Text('清空', style: TextStyle(fontSize: 24)),
                onPressed: () {
                  (_formKey.currentState as FormState).reset();
                }),
          ),
          Expanded(
            flex: 1,
            child: FlatButton(
              child: Text(mViewState == ViewState.AddItemView ? '提交' : '保存',
                  style: TextStyle(fontSize: 24, color: Colors.blue)),
              onPressed: () {
                if ((_formKey.currentState as FormState).validate())
                  _onSubmit();
              },
            ),
          ),
        ],
      )
    ];
    if (mViewState == ViewState.AddItemView)
      items.insert(
        0,
        TextFormField(
          controller: _entry,
          decoration: InputDecoration(
            hintText: 'Entry',
            prefixIcon: Icon(Icons.title),
          ),
          validator: (v) => v.trim().length > 0 ? null : 'Entry不能为空',
        ),
      );
    return items;
  }

  Widget genFloatingActionButtonAction() {
    switch (mViewState) {
      case ViewState.Initial:
        return FloatingActionButton(
          child: FaIcon(FontAwesomeIcons.plug),
          onPressed: openDb,
        );
      default:
        return FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: onAddItem,
        );
    }
  }

  Widget _genDetailView() {
    if (mViewState == ViewState.AddItemView)
      return Form(
        key: _formKey,
        child: Column(
          children: _genDetailWidgets(),
        ),
      );
    else
      return Column(
        children: <Widget>[
          _genHeaderWidget(),
          Expanded(
            child: Form(
              key: _formKey,
              child: Column(
                children: _genDetailWidgets(),
              ),
            ),
          )
        ],
      );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title), actions: <Widget>[
        IconButton(
          icon: Icon(Icons.read_more),
          tooltip: '更新Entries',
          onPressed: () => onUpdateEntries(),
        )
      ]),
      body: FlatPanel(
        margin: 32,
        padding: 32,
        child: _genDetailView(),
      ),
      floatingActionButton: genFloatingActionButtonAction(),
    );
  }
}
